﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Nine;
using Nine.Animations;
using Nine.Graphics;
using Nine.Graphics.Effects;
using Nine.Graphics.Effects.EffectParts;

namespace LevelEditor.EditorSupport
{
    public enum ModelMovementMode
    {
        Translate,
        Rotate,
        Scale,
        PlaceCollisionBox,
        PlaceCollisionSphere,
        PlaceStoryBox,
    }

    public class EditorModels
    {
        private string id;
        public string ID { get { return id; } }

        private Model xnaModel;
        public Model XnaModel { get { return xnaModel; } }

        private Model nineModel;
        public Model NineModel { get { return nineModel; } }

        private string fileName;
        public string FileName { get { return fileName; } }

        public BEPUphysics.Collidables.StaticMesh Mesh;

        public bool GenerateCollisionMesh;
        public bool DisplayShadow;
        public bool DisplayModel;

        private Vector3 position;
        public Vector3 Position
        {
            get { return position; }
            set
            {
                position = value;
                worldMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
            }
        }

        private Vector3 rotation;
        public Vector3 Rotation
        {
            get { return rotation; }
            set
            {
                rotation = value;
                worldMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
            }
        }

        private Vector3 scale;
        public Vector3 Scale
        {
            get { return scale; }
            set
            {
                scale = value;
                worldMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
            }
        }

        private Matrix worldMatrix;
        public Matrix WorldMatrix { get { return worldMatrix; } }

        private BoundingBox box;
        public BoundingBox Box { get { return box; } set { box = value; } }

        public EditorModels(string _id, Model _nineModel, Model _xnaModel, bool _generateCollisionMesh, bool _displayShadow, bool _displayModel, string _fileName, Vector3 _position, Vector3 _scale, Vector3 _rotation)
        {
            id = _id;
            nineModel = _nineModel;
            xnaModel = _xnaModel;
            GenerateCollisionMesh = _generateCollisionMesh;
            DisplayShadow = _displayShadow;
            DisplayModel = _displayModel;
            fileName = _fileName;
            position = _position;
            scale = _scale;
            rotation = _rotation;
            worldMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);

            box = EditorComponents.CreateBoundingBox(nineModel, worldMatrix);
        }
    }

    public class EditorAnimModels
    {
        public string ID;
        public Model model;
        public Vector3 position;
        public Vector3 scale;
        public Vector3 rotation;
        public BoneAnimation animation;

        public EditorAnimModels(string _id, Model _model, Vector3 _position, Vector3 _scale, Vector3 _rotation)
        {
            ID = _id;
            model = _model;
            position = _position;
            scale = _scale;
            rotation = _rotation;

            animation = new BoneAnimation(model, null, model.GetAnimation(0));
            animation.Play();
        }
    }

    public static class LevelObjects
    {
        public static List<EditorModels> StillModels = new List<EditorModels>();
        public static List<EditorAnimModels> AnimatedModels = new List<EditorAnimModels>();
        public static List<BoundingBox> EventBoxes = new List<BoundingBox>();
        public static List<BoundingSphere> EventSpheres = new List<BoundingSphere>();

        public static ModelMovementMode MoveMode = ModelMovementMode.Translate;
        //public static ModelDrawingMode DrawMode = ModelDrawingMode.GraphicsOnly;
        public static bool DrawModels = true;
        public static bool DrawBounds = false;
        public static bool DrawEvents = true;
        public static List<EditorModels> SelectedModels = new List<EditorModels>();
        public static int SelectedModelIndex = 0;

        // Bounding box pieces for creating events used in the place functionality
        public static bool EditingWidthLength = false;
        public static bool EditingHeight = false;
        public static Vector3 CreateMin = Vector3.Zero;
        public static Vector3 CreateMax = Vector3.Zero;

        // Bounding sphere pieces for events
        public static Vector3 CreateCenter = Vector3.Zero;
        public static float CreateRadius = 0.0f;

        // Create lights. Change position vector and farplane to light larger area (quality suffers)
        public static Matrix LightView = Matrix.CreateLookAt(new Vector3(100, 100, 300), Vector3.Zero, Vector3.UnitZ);
        public static Matrix LightProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.Pi / 2.5f, 1, 8.0f, 800.0f);
    }
}
